package cn.pink.core.gen;

import cn.pink.core.gen.entity.Entity;
import cn.pink.core.gen.proxy.DistrClass;
import cn.pink.core.support.ClassFinder;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.*;

/**
 *
 * @author Pink
 */
public class GenUtils {
	
	//-----------------------------------------------------------------------------------------
	// 获取class的注解字段
	
	/**
	 * 从class的注解中获取name对应的值
	 */
	public static Object getClassAnnotationField(Class<?> clazz, Class<? extends Annotation> annotationClazz, String name) throws Exception {
		Annotation annotation = clazz.getAnnotation(annotationClazz);
		Method method = annotationClazz.getMethod(name);
		
		return method.invoke(annotation);
	}

	/**
	 * 从class的Entity注解中获取name对应的值
	 */
	public static Object getEntityField(Class<?> clazz, String name) throws Exception {
		return getClassAnnotationField(clazz, Entity.class, name);
	}
	
	/**
	 * 从class的DistrClass注解中获取name对应的值
	 */
	public static Object getDistrClassField(Class<?> clazz, String name) throws Exception {
		return getClassAnnotationField(clazz, DistrClass.class, name);
	}
	
	//-----------------------------------------------------------------------------------------
	// 获取enum的注解字段
	
	/**
	 * 从enum的注解中获取name对应的值
	 */
	public static Object getEnumAnnotationField(Object enumm, Class<? extends Annotation> annotationClazz, String name) throws Exception {
		String enumName = ((Enum<?>)enumm).name();
		Annotation annotation = enumm.getClass().getField(enumName).getAnnotation(annotationClazz);
		if (annotation == null) {
			return null;
		}
		
		Method method = annotationClazz.getMethod(name);

		return method.invoke(annotation);
	}

	//-----------------------------------------------------------------------------------------
	// 获取method的注解字段
	
	/**
	 * 从method的注解中获取name对应的值
	 */
	public static Object getMethodAnnotationField(Method method, Class<? extends Annotation> annotationClazz, String name) throws Exception {
		Annotation annotation = method.getAnnotation(annotationClazz);
		Method mKey = annotationClazz.getMethod(name);
		
		return mKey.invoke(annotation);
	}
	
	//-----------------------------------------------------------------------------------------

	/**
	 * 获取要生成的class及其method
	 */
	public static Map<Class<?>, List<Method>> findMethodNeedToGen(String packageName, 
			Class<? extends Annotation> classAnno, Class<? extends Annotation> methodAnno) throws Exception {
		Map<Class<?>, List<Method>> result = new LinkedHashMap<>();
		
		// 获取源文件夹下所有类
		List<Class<?>> sources = ClassFinder.getAllClass(packageName);
		
		// 遍历所有类，处理带有DistrClass注解的方法
		for (Class<?> clazz : sources) {
			if (classAnno != null && !clazz.isAnnotationPresent(classAnno)) {
				continue;
			}
			
			Method[] ms = clazz.getMethods();
			List<Method> methods = new ArrayList<>();
			
			// 遍历所有方法，如果有DistrMethod注解，则加入list
			for (Method m : ms) {
				if (m.isAnnotationPresent(methodAnno)) {
					methods.add(m);
				}
			}
			
			// 如果有DistrMethod注解的方法，则加入待创建数据
			if (!methods.isEmpty()) {
				// 排序
				Collections.sort(methods, new Comparator<Method>() {

					@Override
					public int compare(Method o1, Method o2) {
						return o1.toString().compareTo(o2.toString());
					}
				});
				
				result.put(clazz, methods);
			}
		}
		
		return result;
	}
	
	public static String primitiveTowrapper(String primitive) {
		String wrapper = primitive;
		switch (primitive) {
		case "int":
			wrapper = "Integer";
			break;
		case "long":
			wrapper = "Long";
			break;
		case "double":
			wrapper = "Double";
			break;
		case "float":
			wrapper = "Float";
			break;
		case "boolean":
			wrapper = "Boolean";
			break;
		default:
			break;
		}
		
		return wrapper;
	}
}
